<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

namespace App\Service;

use Exception;
use TencentCloud\Common\CommonClient;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Live\V20180801\LiveClient;
use TencentCloud\Live\V20180801\Models\DropLiveStreamRequest;

use function Hyperf\Support\env;

class LiveService
{
    /**
     * 断流
     * @param mixed $streamName
     */
    public static function dropLiveStream($streamName): string|true
    {
        try {
            $cred = new Credential(env('LIVE_SECRET_ID'), env('LIVE_SECRET_KEY'));
            $client = new LiveClient($cred, '');
            // 实例化一个请求对象,每个接口都会对应一个request对象
            $req = new DropLiveStreamRequest();

            $params = [
                'StreamName' => $streamName,
                'DomainName' => env('LIVE_PUSH_STREAM_DOMAIN'),
                'AppName' => env('LIVE_APP_NAME'),
            ];
            $req->fromJsonString(json_encode($params));

            // 返回的resp是一个DropLiveStreamResponse的实例，与请求对象对应
            $resp = $client->DropLiveStream($req);
            return true;
        } catch (TencentCloudSDKException $e) {
            return $e->getMessage();
        }
    }

    /**
     * 恢复推流
     */
    public static function resumeLiveStream($streamName): string|true
    {
        try {
            $cred = new Credential(env('LIVE_SECRET_ID'), env('LIVE_SECRET_KEY'));
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint('live.tencentcloudapi.com');
            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            $client = new CommonClient('live', '2018-08-01', $cred, '', $clientProfile);
            $params = [
                'StreamName' => $streamName,
                'DomainName' => env('LIVE_PUSH_STREAM_DOMAIN'),
                'AppName' => env('LIVE_APP_NAME'),
            ];
            $client->callJson('ResumeLiveStream', json_decode(json_encode($params)));
            return true;
        } catch (TencentCloudSDKException $e) {
            return $e->getMessage();
        }
    }

    /**
     * 禁止推流
     */
    public static function forbidLiveSteam($streamName, $resumeTime): string|true
    {
        try {
            $cred = new Credential(env('LIVE_SECRET_ID'), env('LIVE_SECRET_KEY'));
            $httpProfile = new HttpProfile();
            $httpProfile->setEndpoint('live.tencentcloudapi.com');
            $clientProfile = new ClientProfile();
            $clientProfile->setHttpProfile($httpProfile);
            $client = new CommonClient('live', '2018-08-01', $cred, '', $clientProfile);
            $params = [
                'AppName' => env('LIVE_APP_NAME'),
                'DomainName' => env('LIVE_PUSH_STREAM_DOMAIN'),
                'StreamName' => $streamName,
                'ResumeTime' => date('c', $resumeTime),
            ];
            $resp = $client->callJson('ForbidLiveStream', json_decode(json_encode($params)));
            return true;
        } catch (TencentCloudSDKException $e) {
            return $e->getMessage();
        }
    }

    /**
     * 生成推流地址
     * @param $streamName
     * @param string $protocol
     * @return string
     */
    public static function createPushStreamAddress($streamName, string $protocol = 'rtmp'): string
    {
        $txTime = dechex(time() + env('LIVE_PUSH_STREAM_EXPIRE'));
        $txSecret = md5(env('LIVE_PUSH_STREAM_KEY') . $streamName . $txTime);
        return $protocol . '://' . env('LIVE_PUSH_STREAM_DOMAIN') . '/' . env('LIVE_APP_NAME', 'live') . '/' . $streamName . '?txSecret=' . $txSecret . '&txTime=' . $txTime;
    }

    /**
     * 生成播放地址
     * @param $streamName
     * @param string $protocol
     * @return string
     * @throws Exception
     */
    public static function createPlayAddress($streamName, string $protocol = 'flv'): string
    {
        if (! in_array($protocol, ['flv', 'm3u8', 'rtmp', 'webrtc'])) {
            throw new Exception('不支持该协议');
        }
        $txTime = dechex(time() + env('LIVE_PLAY_STREAM_EXPIRE'));
        $txSecret = md5(env('LIVE_PLAY_STREAM_KEY') . $streamName . $txTime);
        $domain = env('LIVE_PLAY_STREAM_DOMAIN');
        $appName = env('LIVE_APP_NAME', 'live');
        return match ($protocol) {
            'flv' => "https://{$domain}/{$appName}/{$streamName}.flv?txSecret={$txSecret}&txTime={$txTime}",
            'm3u8' => "https://{$domain}/{$appName}/{$streamName}.m3u8?txSecret={$txSecret}&txTime={$txTime}",
            'rtmp' => "rtmp://{$domain}/{$appName}/{$streamName}?txSecret={$txSecret}&txTime={$txTime}",
            'webrtc' => "webrtc://{$domain}/{$appName}/{$streamName}?txSecret={$txSecret}&txTime={$txTime}",
        };
    }
}
